/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package mb;

import beans.Fatura;
import beans.HistoricoFatura;
import beans.Usuario;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.PdfWriter;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.RequestScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.IOUtils;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.DefaultStreamedContent;
import org.primefaces.model.StreamedContent;
import org.springframework.util.DigestUtils;
import rn.FaturaRN;
import util.Utilidades;
import rn.HistoricoFaturaRN;

/**
 *
 * @author Caio
 */
@ManagedBean(name="controllerFatura")
@RequestScoped
public class ControllerFatura implements Serializable {
    
    public ControllerFatura(){}
    
    @ManagedProperty(value="#{fatura}")
    private Fatura fatura;

    private List<Fatura> lista;
    
    private DataModel listaDataModel;
    
    private StreamedContent file;
    
    private String md5;
        
    public void limpar() {
        setFatura(new Fatura());
    }

    ////////////////////////////////////////////////////////////////////////////   
    
    public DataModel getListaDM() {
        FaturaRN rn = new FaturaRN();
        this.listaDataModel = new ListDataModel(rn.listar());
        return this.listaDataModel;
    }
    
    public List<Fatura> getLista() {
        FaturaRN rn = new FaturaRN();
        this.lista = rn.listar();
        return this.lista;
    }    
       
    public void salvar(){
        FaturaRN rn = new FaturaRN();
        rn.salvar(this.fatura);
        limpar();
        FacesContext context = FacesContext.getCurrentInstance();            
        context.addMessage(null, new FacesMessage("Cadastrado com Sucesso"));       
    }
    
    public void remover(){
        FaturaRN rn = new FaturaRN();
        this.fatura= (Fatura)this.listaDataModel.getRowData();
        rn.excluir(this.fatura);        
        limpar();   
        FacesContext context = FacesContext.getCurrentInstance();    
        context.addMessage(null, new FacesMessage("Excluído com Sucesso"));
    }
  

    public void alterar() {
        FaturaRN rn = new FaturaRN();
        rn.atualizar(this.fatura);
        limpar();
        FacesContext context = FacesContext.getCurrentInstance();            
        context.addMessage(null, new FacesMessage("Alterado com Sucesso"));
    }
    
    public Fatura carregar(int id){
        FaturaRN rn = new FaturaRN();
        return rn.carregar(id);
    }

    public void prepararAlterar() {
        this.fatura = (Fatura) this.listaDataModel.getRowData();
    }
    
    public void handleFileUpload(FileUploadEvent event) throws Exception {
        InputStream is = event.getFile().getInputstream();
        byte[] array = IOUtils.toByteArray(is);
        byte[] zip = Utilidades.zipBytes(array);
        this.fatura.setArquivo(zip);
        this.fatura.setMd5(md5Spring(array));
        this.fatura.setUsuario(Usuario.capturaLogado());
        salvar();
        Utilidades.enviarEmailFatura(Usuario.capturaLogado().getEmail(), md5Spring(array));
    }
    
    public static String md5Spring(byte[] array){
        byte[] arquivo = DigestUtils.md5Digest(array);
        BigInteger bigInt = new BigInteger(1, arquivo);  
        String output = bigInt.toString(16);
        return output;
    }
    
    public StreamedContent fileDownloadZiped(){
        prepararAlterar();
        //file = new DefaultStreamedContent(new ByteArrayInputStream(fat.getArquivo()),"application/pdf","Arquivo");
        this.file = new DefaultStreamedContent(new ByteArrayInputStream(this.fatura.getArquivo()),"application/zip","Compactado");
        limpar();
        return this.file;
    }
    
    public StreamedContent fileDownloadUnziped() throws IOException{
        prepararAlterar();
        byte[] arquivoDesc = Utilidades.unzipBytes(this.fatura.getArquivo());
        this.file = new DefaultStreamedContent(new ByteArrayInputStream(arquivoDesc),"application/pdf","Descompactado");
        limpar();
        return this.file;
    }
        
    public void carregarFatura() throws IOException{              
        FacesContext fc = FacesContext.getCurrentInstance();
        ExternalContext ec = fc.getExternalContext();
        
        FaturaRN rn = new FaturaRN();
        List<Fatura> faturas = new ArrayList<Fatura>();
        byte[] arquivoBytes = "Vazio".getBytes();
        
        if (this.md5 != null) {
            faturas = rn.buscaPersonalizada("md5", this.md5);
            if (!faturas.isEmpty()) {
                arquivoBytes  = Utilidades.unzipBytes(faturas.get(0).getArquivo());     
            } else {
                arquivoBytes = "Nenhum arquivo encontrado.".getBytes();
            }
        } else {
            arquivoBytes = "Não há hash no link".getBytes();
        }
        
        ec.responseReset();
        ec.setResponseContentType("application/pdf");
        ec.setResponseContentLength(arquivoBytes.length);  

        OutputStream output = ec.getResponseOutputStream();
        output.write(arquivoBytes, 0, arquivoBytes.length);  
        output.flush();  
        output.close();  
        
        //salva o historico da fatura antes de renderizar o pdf
        //IP da request
        String ipAddress = Utilidades.capturarIP();
        
        HistoricoFatura obj = new HistoricoFatura();
        obj.setEndereco_ip(ipAddress);
        obj.setFatura(faturas.get(0));
        
        HistoricoFaturaRN rnHF = new HistoricoFaturaRN();
        rnHF.salvar(obj);
        //fim
        
        fc.responseComplete();
    }
    
    //Deixei para teste, analisar se fica melhor.
    public void download() throws IOException, DocumentException {
        FacesContext context = FacesContext.getCurrentInstance();
        HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse();
        response.setContentType("application/pdf");
        response.setHeader("Content-Disposition", "inline; filename=\"" + "TESTE" + "\"");

        Document document = new Document();
        PdfWriter writer = PdfWriter.getInstance(document, response.getOutputStream());
        document.open();
        // Build document.

        context.responseComplete();
    }
        
    ////////////////////////////////////////////////////////////////////////////
    public Fatura getFatura() {
        return fatura;
    }

    public void setFatura(Fatura fatura) {
        this.fatura = fatura;
    }

    public DataModel getListaDataModel() {
        return listaDataModel;
    }

    public void setListaDataModel(DataModel listaDataModel) {
        this.listaDataModel = listaDataModel;
    }

    public String getMd5() {
        return md5;
    }

    public void setMd5(String md5) {
        this.md5 = md5;
    }
    
}
